/*
 * 
 */

package L298NDriver;

import com.sun.spot.resources.transducers.IOutputPin;
import com.sun.spot.sensorboard.EDemoBoard;
import com.sun.spot.sensorboard.EDemoController;
import com.sun.spot.sensorboard.io.PinDescriptor;

/**
 * This is the L298N Driver class. It will control the L298N H-bridge though the
 * different states.
 * @author JaredSmith
 */
public class L298NDriver implements IL298NDriver {

    private PinDescriptor enableDescriptor;
    private IOutputPin enable;
    private IOutputPin inputA;
    private IOutputPin inputB;
    private EDemoController ctrl;
    /**
     * This is the basic constructor for the L298N Driver.
     * @param enable :the pin on the spot that is connected to the enable pin
     *                on the H-bridge
     *
     * @param inputA :the pin on the spot that is connected to one of the input
     *                pins on the H-bridge
     *
     * @param inputB :the pin on the spot that is connected to the other input
     *                pin on the H-bridge
     */
    public L298NDriver(IOutputPin enable, IOutputPin inputA, IOutputPin inputB, PinDescriptor enableDescriptor){
        this.enable = enable;
        this.inputA = inputA;
        this.inputB = inputB;
        this.enableDescriptor = enableDescriptor;
        ctrl = EDemoBoard.getInstance().getEDemoController();
    }

    /**
     * Moves the motor in direction A by setting input A high and input B low
     * @param duty :the duty cycle that you would like to set your PWM to
     */
    public void PWMDirectionA(int duty){
        ResetPins();
        inputA.setHigh();
        inputB.setLow();
        ctrl.setPDM(enableDescriptor, duty);
    }

    /**
     * Moves the motor in direction B by setting input B high and input A low
     * @param duty :the duty cycle that you would like to set your PWM to
     */
    public void PWMDirectionB(int duty){
        ResetPins();
        inputB.setHigh();
        inputA.setLow();
        ctrl.setPDM(enableDescriptor, duty);
    }

    /**
     * Stops the motor by setting both poles of the motor to high and turning
     * the H-bridge fully on
     */
    public void Stop(){
        ResetPins();
        inputA.setLow();
        inputB.setLow();
        enable.setHigh();
    }

    /**
     * Sets the inputs of the motor low and turns the H-bridge low so that the
     * motor goes into free running state
     */
    public void FreeRunning(){
        ResetPins();
        enable.setLow();
        inputA.setLow();
        inputB.setLow();
    }

    /**
     * This method is for setting the motor moving in direction A and ignoring
     * PWM
     */
    public void DirectionA() {
        ResetPins();
        inputA.setHigh();
        inputB.setLow();
        enable.setHigh();
    }

    /**
     * This method is for setting the motor moving in direction A and ignoring
     * PWM
     */
    public void DirectionB() {
        ResetPins();
        inputB.setHigh();
        inputA.setLow();
        enable.setHigh();
    }

    /**
     * This method will reset the pins and the PWM signal before changing states
     */
    public void ResetPins() {
        // As noted in the theory of operation for the Sun SPOT, setting the PWM
        // to 0 will turn the signal off completely.
        ctrl.setPDM(enableDescriptor, 0);
        enable.setLow();
        inputA.setLow();
        inputB.setLow();
    }
}
